#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>

#include <QtDebug>

#include "Camera.h"

#include "MJPEGClient.h"


MJPEGClient::MJPEGClient( QString hostname )
{
    m_hostname = hostname;
    nam = new QNetworkAccessManager();
    namCtrl = new QNetworkAccessManager();
    reply = 0;

    m_bytes.clear();
}

MJPEGClient::~MJPEGClient()
{
    m_bytes.clear();
}

void MJPEGClient::getVideoFromStreamer()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=stream" );

    reply = nam->get( QNetworkRequest( qurl ) );
    // NOTE: Store QNetworkReply pointer (maybe into caller).
    // When this HTTP request is finished you will receive this same
    // QNetworkReply as response parameter.
    // By the QNetworkReply pointer you can identify request and response

    connect( this->reply, SIGNAL( readyRead() ), this, SLOT( readyRead() ) );
    connect( nam, SIGNAL( finished( QNetworkReply * ) ), this, SLOT( finished() ) );

    reply->waitForReadyRead( -1 );

}

void MJPEGClient::cmdProcessing(QKeyEvent *event)
{
    QString url = "http://" + m_hostname + ":8080/?action=command&";

    switch (event->key())
    {
	case Qt::Key_0:
	    //qDebug() << "reset cam pan tilt";
	    url = url + "command=reset_pan_tilt";
	    namCtrl->get( QNetworkRequest( QUrl(url) ) );
	    break;

	case Qt::Key_Left:
	    //qDebug() << "cam pan plus";
	    url = url + "command=pan_plus";
	    namCtrl->get( QNetworkRequest( QUrl(url) ) );
	    break;

	case Qt::Key_Right:
	    //qDebug() << "cam pan minus";
	    url = url + "command=pan_minus";
	    namCtrl->get( QNetworkRequest( QUrl(url) ) );
	    break;

	case Qt::Key_Up:
	    //qDebug() << "cam tilt minus";
	    url = url + "command=tilt_minus";
	    namCtrl->get( QNetworkRequest( QUrl(url) ) );
	    break;

	case Qt::Key_Down:
	    //qDebug() << "cam tilt plus";
	    url = url + "command=tilt_plus";
	    namCtrl->get( QNetworkRequest( QUrl(url) ) );
	    break;
    }

}

void MJPEGClient::resetPanTitl()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=command&command=reset_pan_tilt" );
    namCtrl->get( QNetworkRequest( qurl ) );
}

void MJPEGClient::setLookUp()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=command&command=tilt_minus" );
    namCtrl->get( QNetworkRequest( qurl ) );
}

void MJPEGClient::setLookDown()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=command&command=tilt_plus" );
    namCtrl->get( QNetworkRequest( qurl ) );
}

void MJPEGClient::setLookLeft()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=command&command=pan_plus" );
    namCtrl->get( QNetworkRequest( qurl ) );
}

void MJPEGClient::setLookRight()
{
    QUrl qurl( "http://" + m_hostname + ":8080/?action=command&command=pan_minus" );
    namCtrl->get( QNetworkRequest( qurl ) );
}

void MJPEGClient::readyRead()
{
    // no error received?
    if ( reply->error() == QNetworkReply::NoError )
    {

	//qDebug() << "bytes available " << m_bytes.length();

	// Reading bytes from the reply
	m_bytes.append( reply->readAll() );  // bytes
	//QString string( m_bytes ); // string

	// Bytes marking start and end of the image
	QByteArray SOI, EOI;
	SOI.resize(2); SOI[0] = 0xFF; SOI[1] = 0xD8;
	EOI.resize(2); EOI[0] = 0xFF; EOI[1] = 0xD9;

	int posSOI = m_bytes.indexOf( SOI );
	int posEOI = m_bytes.indexOf( EOI );

	if ( posSOI >= 0 && posEOI >= 0 && posSOI < posEOI )
	{
	    //m_mutexCamera.lockForWrite();

	    static QImage pic;

	    if ( pic.loadFromData( m_bytes.mid( posSOI, posEOI-posSOI+2 ) ), "jpg" )
	    {
		m_bytes.remove( 0, posEOI+2 );
		emit gotNewImage( &pic );
	    }
	    else 
	    {		
		if ( !pic.isNull() )
		    qDebug() << "ERROR: pic is not NULL";
	    }

	    //m_mutexCamera.unlock();
	}

    }


}


void MJPEGClient::finished()
{
    if ( reply->error() != QNetworkReply::NoError )
    {	
	QString errString = reply->errorString();
	qDebug() << "ERROR: Video streaming problem (" << errString << ")";
    }
    
    reply->deleteLater();

    QCoreApplication::instance()->quit();
}

